home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Audio, Video & Photo / Songbird 0.7.0 / Songbird_0.7.0_windows-i686-msvc8.exe / jsmodules / WindowUtils.jsm < prev    next >
Text File  |  2008-08-12  |  16KB  |  503 lines

  1. /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* vim: set sw=2 :miv */
  3. /*
  4. //
  5. // BEGIN SONGBIRD GPL
  6. //
  7. // This file is part of the Songbird web player.
  8. //
  9. // Copyright(c) 2005-2008 POTI, Inc.
  10. // http://songbirdnest.com
  11. //
  12. // This file may be licensed under the terms of of the
  13. // GNU General Public License Version 2 (the "GPL").
  14. //
  15. // Software distributed under the License is distributed
  16. // on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
  17. // express or implied. See the GPL for the specific language
  18. // governing rights and limitations.
  19. //
  20. // You should have received a copy of the GPL along with this
  21. // program. If not, go to http://www.gnu.org/licenses/gpl.html
  22. // or write to the Free Software Foundation, Inc.,
  23. // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  24. //
  25. // END SONGBIRD GPL
  26. //
  27. */
  28.  
  29. /**
  30.  * \file  WindowUtils.jsm
  31.  * \brief Javascript source for the window utility services.
  32.  */
  33.  
  34. //------------------------------------------------------------------------------
  35. //
  36. // Window utility JSM configuration.
  37. //
  38. //------------------------------------------------------------------------------
  39.  
  40. EXPORTED_SYMBOLS = ["WindowUtils"];
  41.  
  42.  
  43. //------------------------------------------------------------------------------
  44. //
  45. // Window utility imported services.
  46. //
  47. //------------------------------------------------------------------------------
  48.  
  49. Components.utils.import("resource://app/jsmodules/DOMUtils.jsm");
  50. Components.utils.import("resource://app/jsmodules/SBDataRemoteUtils.jsm");
  51. Components.utils.import("resource://app/jsmodules/StringUtils.jsm");
  52.  
  53.  
  54. //------------------------------------------------------------------------------
  55. //
  56. // Window utility defs.
  57. //
  58. //------------------------------------------------------------------------------
  59.  
  60. const Cc = Components.classes;
  61. const Ci = Components.interfaces;
  62. const Cr = Components.results
  63.  
  64.  
  65. //------------------------------------------------------------------------------
  66. //
  67. // Window utility services.
  68. //
  69. //------------------------------------------------------------------------------
  70.  
  71. var WindowUtils = {
  72.   /**
  73.    * \brief Open the modal dialog specified by aURL.  The parent window of the
  74.    *        dialog is specified by aParent.  The name of the dialog is specified
  75.    *        by aName.  The dialog options are specified by aOptions.  Pass the
  76.    *        arguments specified by the array aInArgs in an nsIDialogParamBlock
  77.    *        to the dialog.  The arguments may be strings or nsISupports.
  78.    *        Strings may be specified as locale string bundle keys.  In addition,
  79.    *        if an array of strings is specified as an argument, the first string
  80.    *        is the locale key for a formatted string, and the remaining strings
  81.    *        are the format arguments.  Strings are interpreted as locale keys if
  82.    *        they're wrapped in "&;" (e.g., "&local.string;"); otherwise, they're
  83.    *        interpreted as literal strings.
  84.    *        Set the value field of the objects within the array aOutArgs to the
  85.    *        arguments returned by the dialog.
  86.    *        A locale string bundle may be optionally specified by aLocale.  If
  87.    *        one is not specified, the Songbird locale bundle is used.
  88.    *        Return true if the dialog was accepted.
  89.    *
  90.    * \param aParent             Dialog parent window.
  91.    * \param aURL                URL of dialog chrome.
  92.    * \param aName               Dialog name.
  93.    * \param aOptions            Dialog options.
  94.    * \param aInArgs             Array of arguments passed into dialog.
  95.    * \param aOutArgs            Array of argments returned from dialog.
  96.    * \param aLocale             Optional locale string bundle.
  97.    *
  98.    * \return                    True if dialog accepted.
  99.    */
  100.  
  101.   openModalDialog: function WindowUtils_openModalDialog(aParent,
  102.                                                         aURL,
  103.                                                         aName,
  104.                                                         aOptions,
  105.                                                         aInArgs,
  106.                                                         aOutArgs,
  107.                                                         aLocale) {
  108.     // Set the dialog arguments.
  109.     var dialogPB = null;
  110.     if (aInArgs)
  111.       dialogPB = this._setArgs(aInArgs, aLocale);
  112.  
  113.     // Get the options.
  114.     var options = aOptions.split(",");
  115.  
  116.     // Add options for a modal dialog.
  117.     options.push("modal=yes");
  118.     options.push("resizable=no");
  119.  
  120.     // Set accessibility options.
  121.     if (SBDataGetBoolValue("accessibility.enabled"))
  122.       options.push("titlebar=yes");
  123.     else
  124.       options.push("titlebar=no");
  125.  
  126.     // Convert options back to a string.
  127.     options = options.join(",");
  128.  
  129.     // Create a dialog watcher.
  130.     var dialogWatcher = new sbDialogWatcher();
  131.  
  132.     // Open the dialog and check for acceptance.
  133.     var prompter = Cc["@songbirdnest.com/Songbird/Prompter;1"]
  134.                      .createInstance(Ci.sbIPrompter);
  135.     var window = prompter.openDialog(aParent, aURL, aName, options, dialogPB);
  136.     var accepted = dialogWatcher.getAccepted(window);
  137.  
  138.     // Finalize the dialog watcher.
  139.     dialogWatcher.finalize();
  140.  
  141.     // Get the dialog arguments.
  142.     if (aOutArgs)
  143.       this._getArgs(dialogPB, aOutArgs);
  144.  
  145.     return accepted;
  146.   },
  147.  
  148.  
  149.   /**
  150.    * \brief Create and return a dialog parameter block set with the arguments
  151.    *        contained in the array specified by aArgs.  Look up string arguments
  152.    *        as keys in the locale string bundle specified by aLocale; use the
  153.    *        Songbird locale string bundle if aLocale is not specified.
  154.    *
  155.    * \param aArgs               Array of dialog arguments to set.
  156.    * \param aLocale             Optional locale string bundle.
  157.    */
  158.  
  159.   _setArgs: function WindowUtils__setArgs(aArgs, aLocale) {
  160.     // If |aArgs| is already a |nsIArray|, just use it instead.
  161.     if (aArgs instanceof Ci.nsIArray) {
  162.       return aArgs;
  163.     }
  164.     
  165.     // Get a dialog param block.
  166.     var dialogPB = Cc["@mozilla.org/embedcomp/dialogparam;1"]
  167.                      .createInstance(Ci.nsIDialogParamBlock);
  168.  
  169.     /* Put arguments into param block. */
  170.     var stringArgNum = 0;
  171.     for (var i = 0; i < aArgs.length; i++) {
  172.       // Get the next argument.
  173.       var arg = aArgs[i];
  174.  
  175.       // If arg is an nsISupports, add it to the objects field.  Otherwise, add
  176.       // it to the string list.
  177.       if (arg instanceof Ci.nsISupports) {
  178.         if (!dialogPB.objects) {
  179.           dialogPB.objects = Cc["@songbirdnest.com/moz/xpcom/threadsafe-array;1"]
  180.                                .createInstance(Ci.nsIMutableArray);
  181.         }
  182.         dialogPB.objects.appendElement(arg, false);
  183.       } else {
  184.         dialogPB.SetString(stringArgNum, this._getArgString(arg, aLocale));
  185.         stringArgNum++;
  186.       }
  187.     }
  188.  
  189.     return dialogPB;
  190.   },
  191.  
  192.  
  193.   /**
  194.    * \brief Get the dialog arguments from the parameter block specified by
  195.    *        aDialogPB and return them in the value field of the objects within
  196.    *        the array specified by aArgs.
  197.    *
  198.    * \param aDialogPB           Dialog parameter block.
  199.    * \param aArgs               Array of dialog arguments to get.
  200.    */
  201.  
  202.   _getArgs: function WindowUtils__getArgs(aDialogPB, aArgs) {
  203.     // Get arguments from param block.
  204.     for (var i = 0; i < aArgs.length; i++)
  205.         aArgs[i].value = aDialogPB.GetString(i);
  206.   },
  207.  
  208.  
  209.   /**
  210.    * \brief Parse the argument specified by aArg and return a formatted,
  211.    *        localized string using the locale string bundle specified by
  212.    *        aLocale.  If aLocale is not specified, use the Songbird locale
  213.    *        string bundle.
  214.    *
  215.    * \param aArg                Argument to parse.
  216.    * \param aLocale             Optional locale string bundle.
  217.    *
  218.    * \return                    Formatted, localized string.
  219.    */
  220.  
  221.   _getArgString: function WindowUtils__getArgString(aArg, aLocale) {
  222.     if (aArg instanceof Array) {
  223.       var localeKeyMatch = aArg[0].match(/^&(.*);$/);
  224.       return SBFormattedString(localeKeyMatch[1], aArg.slice(1), aLocale);
  225.     }
  226.     else {
  227.       var localeKeyMatch = aArg.match(/^&(.*);$/);
  228.       if (localeKeyMatch)
  229.         return SBString(localeKeyMatch[1], null, aLocale);
  230.       else
  231.         return aArg;
  232.     }
  233.   }
  234. };
  235.  
  236.  
  237. //------------------------------------------------------------------------------
  238. //------------------------------------------------------------------------------
  239. //
  240. // Dialog watcher services.
  241. //
  242. //   These service provide support for watching dialog windows and determining
  243. // whether a dialog was accepted.
  244. //
  245. //------------------------------------------------------------------------------
  246. //------------------------------------------------------------------------------
  247.  
  248. /**
  249.  * Construct a dialog watcher object.
  250.  */
  251.  
  252. function sbDialogWatcher() {
  253.   this.initialize();
  254. }
  255.  
  256. // Define the object.
  257. sbDialogWatcher.prototype = {
  258.   // Set the constructor.
  259.   constructor: sbDialogWatcher,
  260.  
  261.   //
  262.   // Dialog watcher fields.
  263.   //
  264.   //   _windowInfoList          List of information about windows being watched.
  265.   //   _windowWatcher           Window watcher services.
  266.   //
  267.  
  268.   _windowInfoList: null,
  269.   _windowWatcher: null,
  270.  
  271.  
  272.   //----------------------------------------------------------------------------
  273.   //
  274.   // Dialog watcher services.
  275.   //
  276.   //----------------------------------------------------------------------------
  277.  
  278.   /**
  279.    * Initialize the dialog watcher services.  This is called automatically from
  280.    * the dialog watcher constructor.
  281.    */
  282.  
  283.   initialize: function sbDialogWatcher_initialize() {
  284.     // Initialize the watched window info list.
  285.     this._windowInfoList = [];
  286.  
  287.     // Register for window notifications.
  288.     this._windowWatcher = Cc["@mozilla.org/embedcomp/window-watcher;1"]
  289.                             .getService(Ci.nsIWindowWatcher);
  290.     this._windowWatcher.registerNotification(this);
  291.   },
  292.  
  293.  
  294.   /**
  295.    * Finalize the dialog watcher services.
  296.    */
  297.  
  298.   finalize: function sbDialogWatcher_finalize() {
  299.     // Unregister for window notifications.
  300.     this._windowWatcher.unregisterNotification(this);
  301.  
  302.     // Remove all windows.
  303.     this._removeAllWindows();
  304.  
  305.     // Clear object fields.
  306.     this._windowWatcher = null;
  307.   },
  308.  
  309.  
  310.   /**
  311.    * Return true if the dialog with the window specified by aWindow was
  312.    * accepted.
  313.    *
  314.    * \param aWindow             Window for which to check for acceptance.
  315.    *
  316.    * \return                    True if the dialog was accepted.
  317.    */
  318.  
  319.   getAccepted: function sbDialogWatcher_getAccepted(aWindow) {
  320.     // Get the window info.
  321.     var windowInfo = this._getWindowInfo(aWindow);
  322.  
  323.     return windowInfo ? windowInfo.accepted : false;
  324.   },
  325.  
  326.  
  327.   //----------------------------------------------------------------------------
  328.   //
  329.   // Dialog watcher nsIObserver services.
  330.   //
  331.   //----------------------------------------------------------------------------
  332.  
  333.   /**
  334.    * Handle the observed event specified by aSubject, aTopic, and aData.
  335.    *
  336.    * \param aSubject            Event subject.
  337.    * \param aTopic              Event topic.
  338.    * \param aData               Event data.
  339.    */
  340.  
  341.   observe: function sbDialogWatcher_observe(aSubject, aTopic, aData) {
  342.     switch (aTopic) {
  343.       case "domwindowopened" :
  344.         this._addWindow(aSubject);
  345.         break;
  346.  
  347.       case "domwindowclosed" :
  348.         this._doWindowClosed(aSubject);
  349.         break;
  350.  
  351.       default :
  352.         break;
  353.     }
  354.   },
  355.  
  356.  
  357.   //----------------------------------------------------------------------------
  358.   //
  359.   // Dialog watcher event services.
  360.   //
  361.   //----------------------------------------------------------------------------
  362.  
  363.   /**
  364.    * Handle the load event for the window specified by aWindowInfo.
  365.    *
  366.    * \param aWindowInfo         Window info pertaining to the load event.
  367.    */
  368.  
  369.   _doLoad: function sbDialogWatcher__doLoad(aWindowInfo) {
  370.     var _this = this;
  371.     var func;
  372.  
  373.     // Listen for accept and cancel events.
  374.     var documentElement = aWindowInfo.window.document.documentElement;
  375.     func = function() { _this._doAccept(aWindowInfo); };
  376.     aWindowInfo.domEventListenerSet.add(documentElement,
  377.                                         "dialogaccept",
  378.                                         func,
  379.                                         false);
  380.     func = function() { _this._doCancel(aWindowInfo); };
  381.     aWindowInfo.domEventListenerSet.add(documentElement,
  382.                                         "dialogcancel",
  383.                                         func,
  384.                                         false);
  385.   },
  386.  
  387.  
  388.   /**
  389.    * Handle the window closed event for the window specified by aWindow.
  390.    *
  391.    * \param aWindow             Window pertaining to the closed event.
  392.    */
  393.  
  394.   _doWindowClosed: function sbDialogWatcher__doWindowClosed(aWindow) {
  395.     // Get the window info.  Do nothing if no window info.
  396.     var windowInfo = this._getWindowInfo(aWindow);
  397.     if (!windowInfo)
  398.       return;
  399.  
  400.     // Remove DOM event listeners.
  401.     windowInfo.domEventListenerSet.removeAll();
  402.     windowInfo.domEventListenerSet = null;
  403.   },
  404.  
  405.  
  406.   /**
  407.    * Handle the accept event for the window specified by aWindowInfo.
  408.    *
  409.    * \param aWindowInfo         Window info pertaining to the accept event.
  410.    */
  411.  
  412.   _doAccept: function sbDialogWatcher__doAccept(aWindowInfo) {
  413.     // Set the window as accepted.
  414.     aWindowInfo.accepted = true;
  415.   },
  416.  
  417.  
  418.   /**
  419.    * Handle the cancel event for the window specified by aWindowInfo.
  420.    *
  421.    * \param aWindowInfo         Window info pertaining to the cancel event.
  422.    */
  423.  
  424.   _doCancel: function sbDialogWatcher__doCancel(aWindowInfo) {
  425.     // Set the window as not accepted.
  426.     aWindowInfo.accepted = false;
  427.   },
  428.  
  429.  
  430.   //----------------------------------------------------------------------------
  431.   //
  432.   // Internal dialog watcher services.
  433.   //
  434.   //----------------------------------------------------------------------------
  435.  
  436.   /**
  437.    * Add the window specified by aWindow to the list of windows being watched.
  438.    *
  439.    * \param aWindow             Window to add.
  440.    */
  441.  
  442.   _addWindow: function sbDialogWatcher__addWindow(aWindow) {
  443.     // Do nothing if window has already been added.
  444.     if (this._getWindowInfo(aWindow))
  445.       return;
  446.  
  447.     // Add window to window list.
  448.     var windowInfo = { window: aWindow, accepted: false };
  449.     this._windowInfoList.push(windowInfo);
  450.  
  451.     // Create a window DOM event listener set.
  452.     windowInfo.domEventListenerSet = new DOMEventListenerSet();
  453.  
  454.     // Listen once for window load events.
  455.     var _this = this;
  456.     var func = function() { _this._doLoad(windowInfo); };
  457.     windowInfo.domEventListenerSet.add(aWindow, "load", func, false, true);
  458.   },
  459.  
  460.  
  461.   /**
  462.    * Remove all windows from the list of windows being watched.
  463.    */
  464.  
  465.   _removeAllWindows: function sbDialogWatcher__removeAllWindows() {
  466.     // Remove all windows.
  467.     for (var i = 0; i < this._windowInfoList.length; i++) {
  468.       // Get the window info.
  469.       var windowInfo = this._windowInfoList[i];
  470.  
  471.       // Remove window DOM event listeners.
  472.       if (windowInfo.domEventListenerSet) {
  473.         windowInfo.domEventListenerSet.removeAll();
  474.         windowInfo.domEventListenerSet = null;
  475.       }
  476.     }
  477.     this._windowInfoList = null;
  478.   },
  479.  
  480.  
  481.   /**
  482.    * Return the window info for the window specified by aWindow.
  483.    *
  484.    * \param aWindow             Window for which to return information.
  485.    *
  486.    * \retrurn                   Window information object.
  487.    */
  488.  
  489.   _getWindowInfo: function sbDialogWatcher__getWindowInfo(aWindow) {
  490.     // Find the window information.
  491.     var windowInfo = null;
  492.     for (var i = 0; i < this._windowInfoList.length; i++) {
  493.       if (this._windowInfoList[i].window == aWindow) {
  494.         windowInfo = this._windowInfoList[i];
  495.         break;
  496.       }
  497.     }
  498.  
  499.     return windowInfo;
  500.   }
  501. };
  502.  
  503.